//
//  SlideViewController.swift
//  YOKO
//
//  Created by vivi on 16/5/9.
//  Copyright © 2016年 15Tec. All rights reserved.
//

import UIKit
import SnapKit

enum SlideType {
    case SlidedOut
    case SlidedIn
}

private class SlideContainerView: UIView {
    
    private var __slideConstraint: Constraint!
    private var __mainView: UIView
    private var __slideView: UIView
    private var __slideState: SlideType
    private var __slideOutGesture: UISwipeGestureRecognizer!
    private var __slideInGesture: UISwipeGestureRecognizer!
    
    override init(frame: CGRect) {
        fatalError("Cannot init with init(frame: CGRect)")
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("Cannot init with init?(coder aDecoder: NSCoder)")
    }
    
    init(slideView: UIView, mainView: UIView, withWidthRatio widthRatio: CGFloat) {
        
        __slideView = slideView
        __mainView = mainView
        __slideState = .SlidedIn
        
        //设置阴影
        __mainView.layer.shadowColor = UIColor.blackColor().CGColor
        __mainView.layer.shadowOpacity = 0.2
        __mainView.layer.shadowRadius = 5.0
        __mainView.layer.shadowOffset = CGSizeMake(-5.0, 0.0)
        
        super.init(frame: CGRectZero)
        
        self.addSubview(__slideView)
        self.addSubview(__mainView)

        
        //添加手势控制
        __slideOutGesture = UISwipeGestureRecognizer(target: self, action: #selector(SlideContainerView.slideOutGestureHandler(_:)))
        __slideOutGesture.direction = .Right
        __slideInGesture = UISwipeGestureRecognizer(target: self, action: #selector(SlideContainerView.slideInGestureHandler(_:)))
        __slideInGesture.direction = .Left
        self.addGestureRecognizer(__slideOutGesture)
        self.addGestureRecognizer(__slideInGesture)
        
        __slideView.snp_makeConstraints() {
            make in
            __slideConstraint = make.right.equalTo(self.snp_left).constraint
            make.top.equalTo(self)
            make.bottom.equalTo(self)
            make.width.equalTo(self).multipliedBy(widthRatio)
        }
        __mainView.snp_makeConstraints() {
            make in
            make.top.equalTo(self)
            make.bottom.equalTo(self)
            make.width.equalTo(self)
            make.left.equalTo(__slideView.snp_right)
        }
    }
    
    func slideOut() {
        __slideState = .SlidedOut
        
        UIView.animateWithDuration(0.3, delay: 0.0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0.5, options: .CurveEaseInOut, animations:
            {
                () -> Void in
                self.__slideConstraint.updateOffset(self.__slideView.frame.width - 10)
                self.layoutIfNeeded()
            }, completion: nil)
    }
    
    @objc func slideOutGestureHandler(gesture: UISwipeGestureRecognizer) {
        if __slideState == .SlidedIn {
            slideOut()
        }
    }
    
    func slideIn() {
        __slideState = .SlidedIn
        
        UIView.animateWithDuration(0.3, delay: 0.0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0.5, options: .CurveEaseInOut, animations:
            {
                () -> Void in
                self.__slideConstraint.updateOffset(0)
                self.layoutIfNeeded()
            }, completion: nil)
    }
    
    @objc func slideInGestureHandler(gesture: UISwipeGestureRecognizer) {
        if __slideState == .SlidedOut {
            slideIn()
        }
    }
    
    private override func didMoveToSuperview() {
        
        super.didMoveToSuperview()
        
        //一个容器类占满了整个superview
        if let superview = self.superview {
            self.snp_makeConstraints {
                make in
                make.edges.equalTo(superview)
            }
        }
    }
    
    override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
        
        func isAncestorView(ancestorView: UIView, subView: UIView) -> Bool {
            var fatherView = subView.superview
            while fatherView != nil {
                if (fatherView! === ancestorView) { return true }
                fatherView = fatherView?.superview
            }
            return false
        }
        
        //在这里如果点击事件发生在__mainView当中，那么我们将收起slideView
        let originHitTestViewOrNil = super.hitTest(point, withEvent: event)
        if let originHitTestView = originHitTestViewOrNil {
            if __slideState == .SlidedOut && isAncestorView(__mainView, subView: originHitTestView) {
                //如果当前状态在slideOut状态并且点击事件发生在__mainView当中，那么忽略它
                slideIn()
                return nil
            }
        }
        
        return originHitTestViewOrNil
    }
}

class SlideViewController: UIViewController
{
    required init?(coder aDecoder: NSCoder) {
        fatalError("Cannot init SlideViewController from init?(coder aDecoder: NSCoder)")
    }
    
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        fatalError("Cannot init SlieViewController from init(nib:bundle)")
    }
    
    private var __mainVC: UIViewController!
    private var __slideVC: UIViewController!
    private var __slideContainerView: SlideContainerView!
    
    var mainVC: UIViewController! { return __mainVC }
    var slideVC: UIViewController! { return __slideVC }
    
    var slideState: SlideType {
        return __slideContainerView.__slideState
    }
    
    init(mainViewController: UIViewController, menuViewController: UIViewController, withWidthRatio widthRatio: CGFloat) {
        
        super.init(nibName: nil, bundle: nil)
        
        self.addChildViewController(mainViewController)
        self.addChildViewController(menuViewController)
        __mainVC = mainViewController
        __slideVC = menuViewController
        __slideContainerView = SlideContainerView(slideView: __slideVC.view, mainView: __mainVC.view, withWidthRatio: 0.75)
        self.view.addSubview(__slideContainerView)
    }
    
    func slideOut() {
        //外层接口
        __slideVC.viewWillAppear(true)
        __slideContainerView.slideOut()
        __slideVC.viewDidAppear(true)
    }
    
    func slideIn() {
        //外层接口
        __slideVC.viewWillDisappear(true)
        __slideContainerView.slideIn()
        __slideVC.viewDidDisappear(true)
    }
}
